/*
 * =====================================================================================
 *
 *       Filename:  cl_value_ptr.hxx
 *
 *    Description:  a smart ptr facility
 *
 *        Version:  1.0
 *        Created:  02/15/2010 09:18:35 AM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Ken Chen (Ziliang), zlchen.ken@gmail.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_VALUE_PTR_HXX_
#define _CL_VALUE_PTR_HXX_

#include <algorithm>

namespace neo
{
template<typename T>
class VPTraits
{
public:
	static T* clone(const T* p)
	{
		return new T(*p);
	}
};

template<typename T>
class ValuePtr
{
public:
	explicit ValuePtr(T* p = 0) : m_p(p)
	{
	}

	~ValuePtr()
	{
		delete m_p;
	}

	T& operator*() const
	{
		return *m_p;
	}

	T* operator->() const
	{
		return m_p;
	}

	void swap(ValuePtr& other)
	{
		std::swap(m_p, other.m_p);
	}

	ValuePtr(const ValuePtr& other)
		: m_p(createFrom(other.m_p))
	{
	}

	ValuePtr& operator=(const ValuePtr& other)
	{
		ValuePtr temp(other);
		swap(temp);

		return *this;
	}

	template<typename U>
	ValuePtr(const ValuePtr<U>& other)
		: m_p(createFrom(other.m_p))
	{
	}

	template<typename U>
	ValuePtr& operator=(const ValuePtr<U>& other)
	{
		ValuePtr temp(other);
		swap(temp);

		return *this;
	}

private:
	template<typename U>
	T* createFrom(const U* p) const
	{
		return p ? VPTraits<U>::clone(p) : 0;
	}

	template<typename U> friend class ValuePtr;

	T* m_p;
};

// Usage
} // neo

#endif //_CL_VALUE_PTR_HXX_

